//
//  VideoPrizeClawViewController.m
//  MyApp
//
//  Created by Don on 2017/8/22.
//
//

#import "VideoPrizeClawViewController.h"
#import "UIImage+Color2Image.h"
#import "UIImage+CacheViaName.h"
#import "UIColor+HexColor.h"
#import "UINavigationController+FDFullscreenPopGesture.h"
#import "UIViewController+MMGNavigationBar.h"

#import "PrizeClawVideoHandler.hpp"

#import "MMGPrizeClawOpenGLView.h"
#import "MMGJoyStickView.h"

//#import "MMGSocketClient.h"
#import "MMGVideoPrizeClawView.h"
#import "SoundManager.h"
#import "IAPManager.h"
#import "MMGProduceModel.h"


#import "MMGCustomNavigationBar.h"


void pcvFrameDidReadyCallback(void *ref,int videlWidth, int videoHeight,int glViewWidth, int glViewHeight) {
    if (ref == NULL) {
        return;
    }
    
//    usleep(1000*100);
    VideoPrizeClawViewController *vpcVC = (__bridge VideoPrizeClawViewController *)ref;
    __block BOOL glContextIsReady = NO;
    if (vpcVC.vpcViewModel.glContextIsReadySignal) {
        [vpcVC.vpcViewModel.glContextIsReadySignal subscribeNext:^(id  _Nullable x) {
            if (x) {
                glContextIsReady = YES;
            }
        }];
    }
    vpcVC.vpcViewModel.glViewHeight = glViewHeight;
    vpcVC.vpcViewModel.glViewWidth = glViewWidth;
    vpcVC.vpcViewModel.videoWidth = videlWidth;
    vpcVC.vpcViewModel.videoHeight = videoHeight;
    do {
        //阻塞视频帧解码线程，防止openGL 保证context创建完成后再调用 renderer_init()
        DLog(@"pcvFrameDidReadyCallback sleep %d",glContextIsReady);
    } while (!glContextIsReady);
    
    
}
void pcvFrameAvailableCallback(void *ref,uint8_t *frame) {
    
//    printf("VideoPrizeClawViewController :%p",ref);
    if (ref == NULL) {
        return;
    }
    VideoPrizeClawViewController *vpcVC = (__bridge VideoPrizeClawViewController *)ref;
    [vpcVC renderFrame:frame videoWidth:vpcVC.vpcViewModel.videoWidth videoHeight:vpcVC.vpcViewModel.videoHeight screenWidth:vpcVC.vpcViewModel.glViewWidth screenHeight:vpcVC.vpcViewModel.glViewHeight];
//    DLog(@"VideoPrizeClawViewController:%@ frame available ",ref);
}
void pcvFrameErrorCallback(void *ref , const int error) {
    if (ref == NULL) {
        return;
    }
    printf("VideoPrizeClawViewController:%p error :%d ",ref,error);
    VideoPrizeClawViewController *vpcVC = (__bridge VideoPrizeClawViewController *)ref;
    [vpcVC frameError:""];
    
}

static NSString* const kMMG_PrizeclawBackgroundMusicName = @"SunnyIslandAdventure.mp3";

@interface VideoPrizeClawViewController ()
@property (nonatomic, strong) MMGVideoPrizeClawView *prizeClawView;
@property (nonatomic, strong) RACDisposable *enterBackgroundDisposable;
@property (nonatomic, strong) RACDisposable *willTerminateDisposable;
@property (nonatomic, strong) RACDisposable *willEnterForegroundDisposable;

@property (nonatomic, strong) MMGCustomNavigationBar *customNavigationBar;
@end

@implementation VideoPrizeClawViewController {
    PrizeClawVideoHandler *handler;
    dispatch_queue_t videoStreamQueue;
    
}

#pragma mark - lifecycle
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    [self setUpUI];
    
    videoStreamQueue = dispatch_queue_create("com.memego.videoStream.queue", DISPATCH_QUEUE_SERIAL);
    
    //app返回后台挂起
    MMGWeakSelf(weakSelf);
    self.enterBackgroundDisposable = [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIApplicationDidEnterBackgroundNotification object:nil] subscribeNext:^(NSNotification *notification) {
        DLog(@"--------- UIApplicationDidEnterBackgroundNotification -----------");
       // @synchronized(weakSelf)
        {
            //进入后台无需发送QUIT信号
            [weakSelf closeVideoStream];
            [[SoundManager sharedManager] stopMusic];
        }
        
        
    }];
    
    self.willEnterForegroundDisposable= [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIApplicationDidBecomeActiveNotification object:nil] subscribeNext:^(NSNotification *notification) {
        
//        [weakSelf starVideoGame];
        DLog(@"--------- UIApplicationWillEnterForegroundNotification current thread %@-----------",[NSThread currentThread]);
        [weakSelf.vpcViewModel starSocket];
        
        [[SoundManager sharedManager]stopMusic];
        [[SoundManager sharedManager]playMusic:kMMG_PrizeclawBackgroundMusicName looping:YES fadeIn:YES];
    }];
    
    self.willTerminateDisposable  = [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIApplicationWillTerminateNotification object:nil] subscribeNext:^(NSNotification *notification) {
        DLog(@"--------- UIApplicationWillTerminateNotification -----------");
        [weakSelf stopAllThings];
    }];
    
    [RACObserve(self,self.vpcViewModel.cameraChannel) subscribeNext:^(NSNumber *  _Nullable channel) {
        DLog(@"--------- vpcViewModel.cameraChannel -----------");
        [weakSelf changeVideoChannel:[channel intValue]];
    }];
    [self.vpcViewModel.onDeviceStateDidChangeSignal subscribeNext:^(id  _Nullable x) {
        if ([x intValue] == EMMMGPrizeClawDeviceStateConnected) {
            DLog(@" EMMMGPrizeClawDeviceStateConnected");
            [weakSelf starVideoGame];
        }
    }];
    
    [self.vpcViewModel.timeOut2CloseSignal subscribeNext:^(id  _Nullable x) {
        CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"中奖结果计算超时，您可以在“我的成果”中查看游戏奖励"];
        if (pluginResult) {
            dispatch_async(dispatch_get_global_queue(0, 0), ^{
                if (weakSelf) {
                    
                    if (weakSelf.commandDelegate && weakSelf.command) {
                        [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:weakSelf.command.callbackId];
                    }
                    
                }
            });
            dispatch_async(dispatch_get_main_queue(), ^{
                [weakSelf close];
            });
        }
    }];
    

    [[[[NSNotificationCenter defaultCenter] rac_addObserverForName:(NSNotificationName)kInAppPurchaseTransactionReceiptNotification object:nil] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(NSNotification *notification) {
        DLog(@"--------- kInAppPurchaseTransactionReceiptNotification -----------");
        
//        if ([[MMGGameSYSSettings sharedMMGGameSYSSettings] appIsReviewing]) {
//            
//            if (![notification.object isKindOfClass:[MMGProduceModel class]]) {
//                return ;
//            }
//            MMGProduceModel *produce = (MMGProduceModel *)notification.object;
//            IAPManager *iapManager = [[IAPManager alloc] init];
//            [iapManager payWithProduce:produce.produceId completionBlock:^(NSString *returnKey, BOOL isFinished) {
//                if (isFinished) {
//                    [SVProgressHUD dismiss];
//                    weakSelf.vpcViewModel.dismissIAPAlert = YES;
//                    NSString *transactionReceipt = returnKey;
//                    if (!NSStringIsNullOrEmpty(transactionReceipt)) {
//                        [weakSelf.vpcViewModel sendIAPTransactionReceipt:transactionReceipt];
//                    }
//
//                }else {
//                    
//                    [SVProgressHUD showErrorWithStatus:returnKey];
//                }
//                DLog(@"retun msg %@",returnKey);
//            }];
//        }else
        {
            DLog(@"app is not reviewing %@",notification.object);
            if (![notification.object isKindOfClass:[NSString class]]) {
                return ;
            }
            
            NSString *venderPaymentCommand = (NSString *)notification.object;
            CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:venderPaymentCommand];
            dispatch_async(dispatch_get_global_queue(0, 0), ^{
                if (weakSelf) {
                    if (weakSelf.commandDelegate && weakSelf.command) {
                        [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:weakSelf.command.callbackId];
                    }
                    
                }
            });
            dispatch_async(dispatch_get_main_queue(), ^{
                [weakSelf close];
            });
            
        }
    }];
    
    [self.vpcViewModel.onGameMsgDidReceiveSignal subscribeNext:^(id  _Nullable msg) {
        DLog(@"--------- vpcViewModel.scMassage -----------");
        CDVPluginResult* pluginResult = nil;
        MMGSocketMsgModel *sockekMsg = (MMGSocketMsgModel *)msg;
        if (sockekMsg.type == EMMMGSocketMsgAckTypeNone || sockekMsg.type == EMMMGSocketMsgAckTypeSocketConnected) {
            return ;
        }
        
        if ([sockekMsg isKindOfClass:[MMGSocketMsgModel class]]) {
            
            if (sockekMsg.type == EMMMGSocketMsgAckTypeWinPraize || sockekMsg.type == EMMMGSocketMsgAckTypeWinPraizeAck) {
                //停止下爪后超时计算
                [weakSelf.vpcViewModel stopCountDown];
                if (sockekMsg.code == 0) {

                    pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"WIN"];

                }else {
                    pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"LOSE"];
                }
                
            }else {
                
                if (sockekMsg.code != 0) {
                    /*
                     dispatch_async(dispatch_get_main_queue(), ^{
                     [weakSelf dismissViewControllerAnimated:YES completion:nil];
                     });
                     */
                    
                    pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:sockekMsg.data];
                }else {
                    
                    if(sockekMsg.type == EMMMGSocketMsgAckTypeCancelGame) {
                        
                        /*
                         dispatch_async(dispatch_get_main_queue(), ^{
                         [weakSelf dismissViewControllerAnimated:YES completion:nil];
                         });
                         */
                        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:sockekMsg.data];
                        
                    }
                }
            }
            if (pluginResult) {
                dispatch_async(dispatch_get_global_queue(0, 0), ^{
                    if (weakSelf) {
                        DLog(@".........................send plugin result ：%@................",sockekMsg.data);
                        if (weakSelf.commandDelegate && weakSelf.command) {
                            [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:weakSelf.command.callbackId];
                        }
                        
                    }
                });
                dispatch_async(dispatch_get_main_queue(), ^{
                    [weakSelf close];
                });
            }
        }

    }];
    
    
    //游戏开始
    [self.vpcViewModel.gameStartSignal subscribeNext:^(id  _Nullable x) {
        [weakSelf hideNavigationBarLeftItem:[x boolValue]];
    }];
    
}
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    
    [self.vpcViewModel starSocket];
    
    [UIApplication sharedApplication].idleTimerDisabled=YES;//不自动锁屏
    
}
- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    
    [[SoundManager sharedManager]stopMusic];
    [[SoundManager sharedManager]playMusic:kMMG_PrizeclawBackgroundMusicName looping:YES fadeIn:YES];
}


- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    
    [self stopAllThings];
    
    [UIApplication sharedApplication].idleTimerDisabled= NO;//自动锁屏
    
    [self.enterBackgroundDisposable dispose];
    [self.willEnterForegroundDisposable dispose];
    [self.willTerminateDisposable dispose];
    
    
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)dealloc {
    DLog(@"view controller dealloc ..");
    if (self) {
        [self stopAllThings];
        self.commandDelegate = nil;
        self.command = nil;
    }
}



#pragma mark - private method

- (void)hideNavigationBarLeftItem:(BOOL)hide {
    if (self && self.customNavigationBar) {
        
        if (!hide) {
            [self.customNavigationBar mmg_setTranslucentNavigationBarWithLeftItemImage:@"prize_claw_back_icon.png" title:@"prize_claw_nav_title_icon.png" rightBarButtonItems:nil];
        }else {
            [self.customNavigationBar mmg_setNavigationBarColor:[UIColor mmg_colorWithHex:kMMGColorHex_MainColor] title:@"prize_claw_nav_title_icon.png" tintColor:nil];
        }
    }
    
}
- (void)close {
    //[self.navigationController popViewControllerAnimated:YES];
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)stopAllThings {
    
    @synchronized(self) {
        [self closeVideoStream];
        [self.vpcViewModel closeSocket];
        [[SoundManager sharedManager] stopMusic];
//        [self.prizeClawView tearDownBuffers];
    }
    
}
//TODO: - VIDEO STREAM
- (void)changeVideoChannel:(int)channel {
//    dispatch_async(videoStreamQueue, ^{ @autoreleasepool {
        if (handler) {
            handler->setCameraChannel(channel);
            [MMGGameSYSSettings sharedMMGGameSYSSettings].cameraChannel = channel;
        }
//    }});
}

- (void)closeVideoStream {
    
//    dispatch_async(videoStreamQueue, ^{ @autoreleasepool {
        if (handler) {
            delete handler;
            handler = NULL;
        }
//    }});
}
- (void)starVideoGame {
//    dispatch_async(videoStreamQueue, ^{ @autoreleasepool {
        DLog(@"--------- videoStreamQueue start  current thread %@-----------",[NSThread currentThread]);
        if (NSStringIsNullOrEmpty([MMGGameSYSSettings sharedMMGGameSYSSettings].deviceId) || NSStringIsNullOrEmpty([MMGGameSYSSettings sharedMMGGameSYSSettings].rtmpAddress)) {
            return;
        }
        const char *host = [[MMGGameSYSSettings sharedMMGGameSYSSettings].rtmpAddress UTF8String];
        const char *videoID = [[MMGGameSYSSettings sharedMMGGameSYSSettings].deviceId UTF8String];
        int channel = [MMGGameSYSSettings sharedMMGGameSYSSettings].cameraChannel;
        float width =[UIScreen mainScreen].bounds.size.width;
        float height = 0;
        DLog(@"host %@",[MMGGameSYSSettings sharedMMGGameSYSSettings].rtmpAddress);
        DLog(@"device id %@",[MMGGameSYSSettings sharedMMGGameSYSSettings].deviceId);
        DLog(@"screen width %d",(int)width);
        DLog(@"screen height %d",(int)height);
        
        if (handler == NULL) {
            handler = PrizeClawVideoHandler::getInstance();
        }
        
        handler->starPrizeClawVideo(host, videoID, channel, (int)width, (int)height);
        handler->registerFrameAvailableCallBackFunction((__bridge void *)self, pcvFrameAvailableCallback);
        handler->registerFrameErrorCallBackFunction((__bridge void *)self, pcvFrameErrorCallback);
        handler->registerFrameDidReadyCallBackFunction((__bridge void *)self, pcvFrameDidReadyCallback);
//    }});
}

-(void)frameError:(const char*) errorMsg {
    printf("frame error ..");
}

- (void)renderFrame:(uint8_t *)frame videoWidth:(float)vWidth
        videoHeight:(float)vHeight
        screenWidth:(float)sWidth screenHeight:(float)sHeight{
    
    @synchronized(self)
    {
        if (self && self.prizeClawView) {//放置多线程释放对象后访问，导致崩溃
            [self.prizeClawView renderGL:frame videoWidth:vWidth videoHeight:vHeight screenWidth:sWidth screenHeight:sHeight];
        }
    }
    
}


//TODO: - SET UP UI
- (void)setUpUI {
    self.view.backgroundColor = [UIColor mmg_colorWithHex:kMMGColorHex_MainColor];
    [self mmg_setNavigationBarHidden];
    [self.customNavigationBar mmg_setTranslucentNavigationBarWithLeftItemImage:@"prize_claw_back_icon.png" title:@"prize_claw_nav_title_icon.png" rightBarButtonItems:nil];
    
    MMGWeakSelf(weakSelf);
    [self.customNavigationBar.leftItemSignal subscribeNext:^(id  _Nullable x) {
        [weakSelf close];
    }];
    
    self.vpcViewModel.perRoundCostCoin = [[MMGGameSYSSettings sharedMMGGameSYSSettings].price intValue];
    [self.prizeClawView bindDataWithViewModel:self.vpcViewModel];
   
}
#pragma lazy init

- (MMGVideoPrizeClawViewModel *)vpcViewModel {
    if (!_vpcViewModel) {
        _vpcViewModel = [[MMGVideoPrizeClawViewModel alloc] init];
    }
    
    return _vpcViewModel;
}
- (MMGVideoPrizeClawView *)prizeClawView {
    if (!_prizeClawView) {
        CGFloat naviHeight = self.customNavigationBar.customNavigationBarStatusBarHeight;
        _prizeClawView = [[MMGVideoPrizeClawView alloc] initWithFrame:CGRectMake(0, naviHeight, CGRectGetWidth(self.view.bounds), CGRectGetHeight(self.view.bounds) - naviHeight)];
        
        [self.view addSubview:_prizeClawView];
    }
    return _prizeClawView;
}


- (MMGCustomNavigationBar *)customNavigationBar {
    
    if (!_customNavigationBar) {
        _customNavigationBar = [[MMGCustomNavigationBar alloc] init];
        [self.view addSubview:_customNavigationBar];
    }
    
    return _customNavigationBar;
}
@end
